package wechatpay

import (
	"fmt"
	"log"
	"math/rand"
	"strconv"
	"strings"
	"time"
	"yundian/internel/app/models/paysetting"
)

// ------------ Api v3 - payUtil(支付工具) -----------------//

var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)

// FormatTime time.Time => "yyyyMMddHHmmss."
func FormatTime(t time.Time) string {
	return t.In(BeijingLocation).Format("20060102150405")
}

// ParseTime "yyyyMMddHHmmss" => time.Time.
func ParseTime(value string) (time.Time, error) {
	return time.ParseInLocation("20060102150405", value, BeijingLocation)
}

func TimeStamp() string {
	return strconv.FormatInt(time.Now().Unix(), 10)
}

func FormatIntTime(timeStamp int64) string {
	//返回time对象
	t := time.Unix(timeStamp, 0)
	//返回string
	dateStr := t.Format("20060102150405")
	return dateStr
}

func ConvIntTime(t string) int64 {
	stamp, _ := time.ParseInLocation("20060102150405", t, BeijingLocation)
	return stamp.Unix()
}

func StrTimeToInt(t string) int64 {
	stamp, _ := time.ParseInLocation("2006-01-02 15:04:05", t, BeijingLocation)
	return stamp.Unix()
}

func StrTimeToIntByString(layout string, t string) int64 {
	stamp, _ := time.ParseInLocation(layout, t, BeijingLocation)
	return stamp.Unix()
}

func StrTimeToTime(layout string, t string) string {
	stamp, _ := time.ParseInLocation(layout, t, BeijingLocation)
	return stamp.Format(layout)
}

// 字符串连接
func StrJoin(strs ...string) string {
	return strings.Join(strs, "")
}

// 生成随机字符串
func RandomStr(l int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := []byte(str)
	result := make([]byte, 0)
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < l; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

// 构建签名串
func GenerateSignPay(appid, timestmp, nonceStr, packageStr string, wc *paysetting.PaySetting) (sign string, err error) {
	targetStr := fmt.Sprintf("%s\n%s\n%s\n%s\n",
		appid, timestmp, nonceStr, packageStr)
	log.Println("打印测试数据-构建的 签名串 ", targetStr)
	log.Println("打印测试数据-签名串长度", len(targetStr))
	sign, err = SHA256WithRsaBase64(targetStr, wc)
	return
}

// 构建签名串
func GenerateSign(method, url, timestamp, nonceStr, body string, wc *paysetting.PaySetting) (sign string, err error) {
	targetStr := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n",
		method, url, timestamp, nonceStr, body)
	log.Println("打印测试数据-构建的 签名串 ", targetStr)
	log.Println("打印测试数据-签名串长度", len(targetStr))
	sign, err = SHA256WithRsaBase64(targetStr, wc)
	return
}

// 构建 Token
func GenerateToken(method, url, body string, wc *paysetting.PaySetting) (token string, err error) {
	mchid := wc.MchId                                                      // 服务商商户号
	nonceStr := strings.ToUpper(RandomStr(32))                             // 32位随机字符串
	timestamp := TimeStamp()                                               // 时间戳
	serialNo := wc.SerialNo                                                // 商户证书序列号
	signature, err := GenerateSign(method, url, timestamp, nonceStr, body, wc) //生成签名
	if err != nil {
		return "", err
	}

	authorization := fmt.Sprintf(`%s mchid="%s",nonce_str="%s",signature="%s",timestamp="%s",serial_no="%s"`,
		wechatScheme, mchid, nonceStr, signature, timestamp, serialNo)

	//log.Println("打印测试数据--构建的 Token ", authorization)

	return authorization, err
}

// 获取上月时间范围
func GetLastMonthStartEnd() (int64, int64) {
	now := time.Now()
	lastMonthFirstDay := now.AddDate(0, -1, -now.Day()+1)
	lastMonthStart := time.Date(lastMonthFirstDay.Year(), lastMonthFirstDay.Month(), lastMonthFirstDay.Day(), 0, 0, 0, 0, BeijingLocation)
	lastMonthEndDay := lastMonthFirstDay.AddDate(0, 1, -1)
	lastMonthEnd := time.Date(lastMonthEndDay.Year(), lastMonthEndDay.Month(), lastMonthEndDay.Day(), 23, 59, 59, 0, BeijingLocation)
	//log.Println(lastMonthStart.Format("2006-01-02 15:04:05"), lastMonthEnd.Format("2006-01-02 15:04:05"))

	beginTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthStart.Format("2006-01-02 15:04:05"), BeijingLocation)
	endTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthEnd.Format("2006-01-02 15:04:05"), BeijingLocation)
	//log.Println(beginTimeStamp.Unix(), endTimeStamp.Unix())

	return beginTimeStamp.Unix(), endTimeStamp.Unix()
}

// 获取当月时间范围
func GetNowMonthStartEnd() (int64, int64) {
	now := time.Now()
	nowMonthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, BeijingLocation)
	nowMonthEnd := time.Date(now.Year(), now.Month(), now.Day() - 1, 23, 59, 59, 0, BeijingLocation)
	//log.Println(nowMonthStart.Format("2006-01-02 15:04:05"), nowMonthEnd.Format("2006-01-02 15:04:05"))

	beginTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", nowMonthStart.Format("2006-01-02 15:04:05"), BeijingLocation)
	endTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", nowMonthEnd.Format("2006-01-02 15:04:05"), BeijingLocation)
	//log.Println(beginTimeStamp.Unix(), endTimeStamp.Unix())

	return beginTimeStamp.Unix(), endTimeStamp.Unix()
}

// 获取几天前时间范围
func GetLastDayStartEnd(d int) (int64, int64) {
	now := time.Now()
	lastMonthFirstDay := now.AddDate(0, 0, -(d + 1))
	lastMonthStart := time.Date(lastMonthFirstDay.Year(), lastMonthFirstDay.Month(), lastMonthFirstDay.Day(), 0, 0, 0, 0, BeijingLocation)
	//lastMonthEndDay := lastMonthFirstDay.AddDate(0, 1, -1)
	lastMonthEnd := time.Date(lastMonthFirstDay.Year(), lastMonthFirstDay.Month(), lastMonthFirstDay.Day(), 23, 59, 59, 0, BeijingLocation)
	//log.Println(lastMonthStart.Format("2006-01-02 15:04:05"), lastMonthEnd.Format("2006-01-02 15:04:05"))

	beginTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthStart.Format("2006-01-02 15:04:05"), BeijingLocation)
	endTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthEnd.Format("2006-01-02 15:04:05"), BeijingLocation)
	//log.Println(beginTimeStamp.Unix(), endTimeStamp.Unix())

	return beginTimeStamp.Unix(), endTimeStamp.Unix()
}

// 获取最近多少天
func GetLateDayStartEnd(d int) (int64, int64) {
	now := time.Now()
	lastMonthFirstDay := now.AddDate(0, 0, -(d + 1))
	lastMonthEndDay := now.AddDate(0, 0, -1)
	lastMonthStart := time.Date(lastMonthFirstDay.Year(), lastMonthFirstDay.Month(), lastMonthFirstDay.Day(), 0, 0, 0, 0, BeijingLocation)
	lastMonthEnd := time.Date(lastMonthEndDay.Year(), lastMonthEndDay.Month(), lastMonthEndDay.Day(), 23, 59, 59, 0, BeijingLocation)

	beginTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthStart.Format("2006-01-02 15:04:05"), BeijingLocation)
	endTimeStamp, _ := time.ParseInLocation("2006-01-02 15:04:05", lastMonthEnd.Format("2006-01-02 15:04:05"), BeijingLocation)

	return beginTimeStamp.Unix(), endTimeStamp.Unix()
}

// 时间戳时间  更改为 00:00:00 23:59:59
func TimeConvStartEnd(beginTimeStamp, endTimeStamp int64) (int64, int64) {
	bt := time.Unix(beginTimeStamp, 0)
	et := time.Unix(endTimeStamp, 0)

	start := time.Date(bt.Year(), bt.Month(), bt.Day(), 0, 0, 0, 0, BeijingLocation)
	end := time.Date(et.Year(), et.Month(), et.Day(), 23, 59, 59, 0, BeijingLocation)

	b, _ := time.ParseInLocation("2006-01-02 15:04:05", start.Format("2006-01-02 15:04:05"), BeijingLocation)
	e, _ := time.ParseInLocation("2006-01-02 15:04:05", end.Format("2006-01-02 15:04:05"), BeijingLocation)

	return b.Unix(), e.Unix()
}
